home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 5 / BBS in a Box -Volume V (BBS in a Box) (April 1992).iso / Files / Bus / M / mathsubs.cpt / SIMULT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-05  |  4.6 KB  |  171 lines  |  [TEXT/KAHL]

  1. /***********************************************************************
  2.    Program simult.c by Stan Misel 11/6/84
  3. ***********************************************************************/
  4. #include <stdio.h>
  5. #define MAXEQ 20 /* Max size of arrays to store coefficients */
  6. #define ABS(x) ((x>0)?x:-x) /* Macro routine returns absolute value for any
  7.                              * data type.  Used to avoid having to load the
  8.                              * floating point abs value function fabs()from
  9.                  * the UNIX math library
  10.                  */
  11. double atof(); /* Library function */
  12. void parse(); /* Local function */
  13. void gauss(); /* Local function */
  14. void backtrak(); /* Local function */
  15. main()
  16. {
  17.     char buf[BUFSIZ];
  18.     int n;
  19.     int k;
  20.     int row, col;
  21.     int index;
  22.     double coef[MAXEQ][MAXEQ];
  23.     printf("\n\n\nHow many equations? ");
  24.     gets(buf);
  25.     n = atoi(buf);
  26.     if(n <= 0) {
  27.         printf("Not a valid number\n");
  28.         exit(-1);
  29.     }
  30.     printf("Enter the coefficients of the equations separated byspaces\n");
  31.     printf("Note: The 1st coefficient of the 1st equation cannot be0!\n");
  32.     for (k=1; k<=n; ++k) {
  33.         printf("Equation # %d ==> ",k);
  34.         row = k - 1;
  35.         gets(buf);
  36.         parse(buf,coef[row], n);
  37.     }
  38.     for(index = 0;index < n-1;++index) {
  39.         pivot(coef, n, index);
  40.         gauss(coef,n,index);
  41.     }
  42.     backtrak(coef, n);
  43.     printf("\n\nSolutions:\n");
  44.     for(row=0;row < n;row++)
  45.         printf( "X%d = %f\n",row+1,coef[row][n]);
  46. }
  47. void parse(str, list, nel)
  48. char *str;
  49. double *list;
  50. int nel;
  51. /* Function stuffs blank separated numeric ASCII values into a row of
  52.  * a 2 dimensional array.  The values may be integers or real.
  53.  * Numbers entered may have a leading minus sign, but no plus
  54.  * sign.  Do not input any extraneous spaces or parser will
  55.  * complain and end program.  It will also quit if the number
  56.  * of equations or unknowns is inconsistent.
  57.  */
  58. {
  59.     char tmp[20];
  60.     char *ptmp;
  61.     char c;
  62.     int i = 0;
  63.     while(1) {
  64.         ptmp = tmp;
  65.         while ((c = *str++) != ' ' && c != '\0'){
  66.             *ptmp++ = c;
  67.         }
  68.         *ptmp = '\0';
  69.         *(list+i) = atof(tmp);
  70.         ++i;
  71.         if (i > nel+1){
  72.             printf("too many elements\n");
  73.             exit(-1);
  74.         }
  75.         if(c == '\0')
  76.             break;
  77.     }
  78.     if(i != nel+1) {
  79.         printf("Not enough elements\n");
  80.         exit(-1);
  81.     }
  82. }
  83. pivot(arrayp,nel,index)
  84. double arrayp[][MAXEQ];
  85. int nel;
  86. int index;
  87.  
  88. /* Function implements the PIVOT routine described by Dence to
  89.  * select rows for gaussian elimination that would suffer least
  90.  * from inevitable computer roundoff errors.
  91.  */
  92.  
  93. {
  94.     int row, col;
  95.     int pivrow;
  96.     double max[MAXEQ];
  97.     double x;
  98.     for(row=0; row <= nel; ++row) /* Initialize max array to zeros */
  99.         max[row] = 0.0;
  100.     for (row=index; row < nel; ++row) {
  101.         for(col=index; col < nel; ++col) {
  102.             max[row] = ((x=ABS(arrayp[row][col])) > max[row]) ? x :
  103. max[row];
  104.         }
  105.     }
  106. /* The array max[] contains the values of the largest elements in
  107.  * each of the rows of the array, exclusive of the rightmost element.
  108.  * Now we will find the pivot row.
  109.  */
  110.     pivrow = index;
  111.     for(row=index; row <nel; ++row) {
  112.         max[row] = ABS(arrayp[row][index]) / max[row];
  113.         pivrow = (max[row] >max[pivrow]) ? row : pivrow;
  114.     }
  115. /* We are finished with the array max, so we can use it as a swap
  116.  * area to move our pivot array to the first row.
  117.  */
  118.     for(col = index; col <= nel; ++col)  {
  119.         max[col] = arrayp[index][col];
  120.         arrayp[index][col] = arrayp[pivrow][col];
  121.         arrayp[pivrow][col] = max[col];
  122.     }
  123. } /* End of function */
  124.  
  125. void gauss(arr, nel,index)
  126. double arr[][MAXEQ];
  127. int nel;
  128. int index;
  129.  
  130. /* Function to multiply and add rows in the matrix to reduce
  131.  * to one equation for one unknown.
  132.  */
  133.  
  134. {
  135.     int row, col, i;
  136.     double factor;
  137.  
  138.     for(row = 1+index; row < nel;++row)  {
  139.         factor = -(arr[row][index] / arr[index][index]);
  140.         for(i=index; i <= nel; ++i)  {
  141.             arr[row][i] += factor * arr[index][i];
  142.         }
  143.     }
  144. }
  145.  
  146. void backtrak(array, nel)
  147. double array[][MAXEQ];
  148. int nel;
  149.  
  150. /* Function solves for all variables after the array was reduced by
  151.  * the gaussian elimination function.
  152.  */
  153.  
  154. {
  155.     int step,col,row;
  156.  
  157.     --nel;
  158.     array[nel][nel+1] /= array[nel][nel];
  159.     array[nel][nel]=1;
  160.     for(step = 1; step <= nel; ++step) {
  161.         row=nel-step;
  162.         for(col=row+1;col<= nel;++col) {
  163.             array[row][nel+1] = -array[row][col]*array[col][nel+1]
  164.                 +array[row][nel+1];
  165.             array[row][col]=0;
  166.         }
  167.         array[row][nel+1]=array[row][nel+1]/array[row][row];
  168.         array[row][row]=1;
  169.     }
  170. }
  171.